/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-03-13     73554       the first version
 */
#include "board.h"
#include <rtthread.h>
#include <rtdevice.h>

#define DBG_TAG "ADC"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

#include "user_config.h"

/*********************************************************************************/

/*********************************************************************************/
#define ADC_DEV_NAME        "adc1"      /* ADC 设备名称 */
#define ADC_DEV_CHANNEL     3           /* ADC 通道 */

#define DMA_BUF_COUNT       2000

struct rt_semaphore adc_done_sem;     //接收信号量

rt_adc_device_t pAdcDev;

rt_uint16_t l_AdcDmaBuf_u16[2500];

int_float  g_int_float;


extern ADC_HandleTypeDef hadc1;
extern DMA_HandleTypeDef hdma_adc1;
/*********************************************************************************/

/*********************************************************************************/
#define UART485   "uart1"

struct rt_semaphore uart4_rx_sem;     //接收信号量
static rt_device_t uart1_serial;      //串口设备句柄

static struct serial_configure Uart485Config = RT_SERIAL_CONFIG_DEFAULT;
/*********************************************************************************/

/*********************************************************************************/
/* 初始化ADC外设
 */
int L_ADCInit_i32(void)
{
    /* 查找设备 */
    pAdcDev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
    if (pAdcDev == RT_NULL)
    {
        LOG_E("adc1 not find !");
        return RT_ERROR;
    }

    MX_ADC1_Init(); //初始化ADC
    MX_DMA_Init();  //初始化DMA
    HAL_ADC_MspInit(&hadc1); //初始化其余参数，并将DMA与ADC联系起来

    return RT_EOK;
}
/*********************************************************************************/

/*********************************************************************************/
/* 设置DMA搬运的内存初始地址与长度，开始ADC采集
 */
static void L_StartADCAcquisition(void)
{
    HAL_ADC_Start_DMA(&hadc1, (uint32_t *)l_AdcDmaBuf_u16, DMA_BUF_COUNT);
}
/*********************************************************************************/

/*********************************************************************************/
/* DMA2 Stream0 传输完成中断处理函数
 */
void DMA2_Stream0_IRQHandler(void)
{
    /* enter interrupt */
    LOG_I("DMA2_Stream0_IRQHandler.");
    rt_interrupt_enter();
    HAL_DMA_IRQHandler(&hdma_adc1);
    HAL_ADC_Stop_DMA(&hadc1);  //自动停止ADC和DMA
    rt_sem_release(&adc_done_sem);
    /* leave interrupt */
    rt_interrupt_leave();
}
/*********************************************************************************/

/*********************************************************************************/
/* ADC转换完成回调函数
 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
    LOG_I("HAL_ADC_ConvCpltCallback.");
}
/*********************************************************************************/

/*********************************************************************************/
void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc)
{
    LOG_I("HAL_ADC_ErrorCallback.");
    if (hadc == pAdcDev->parent.user_data)
    {
        LOG_E("HAL_ADC_ErrorCallback called");////////
    }
}
/*********************************************************************************/

/*********************************************************************************/
/* ADC线程入口函数
 */
void G_ADC_thread_entry(void *parameter)
{
    rt_uint8_t UartTx1Buf[100] = {};

    while(1)
    {
        rt_sem_control(&adc_done_sem, RT_IPC_CMD_RESET, (void*) 0); //清一下信号量
        L_StartADCAcquisition();

        rt_err_t res = rt_sem_take(&adc_done_sem, rt_tick_from_millisecond(10));
        if(res != RT_EOK)  //未收到
        {
//            LOG_E("no rx !");
        }
        else
        {
            LOG_I("adc1 get data succ. data1:%d, data2:%d.", l_AdcDmaBuf_u16[0], l_AdcDmaBuf_u16[1]);

            for(int a = 0; a < 2000; a++) //将采集到的adc数据数组通过串口发送
            {
                g_int_float.datau64 = 0;
                g_int_float.dataf = (float)l_AdcDmaBuf_u16[a];
                UartTx1Buf[0] = g_int_float.datau8[0];
                UartTx1Buf[1] = g_int_float.datau8[1];
                UartTx1Buf[2] = g_int_float.datau8[2];
                UartTx1Buf[3] = g_int_float.datau8[3];

                UartTx1Buf[4] = 0x00; //vofa 浮点数协议帧尾
                UartTx1Buf[5] = 0x00;
                UartTx1Buf[6] = 0x80;
                UartTx1Buf[7] = 0x7f;

                rt_device_write(uart1_serial, 0, UartTx1Buf, 8);
                rt_thread_delay(1); //让出cpu
            }

        }


        for(int a = 0; a < 200; a++) //发送200个-100，作为区分两次采集的标志
        {
            g_int_float.datau64 = 0;
            g_int_float.dataf = -100.0f;
            UartTx1Buf[0] = g_int_float.datau8[0];
            UartTx1Buf[1] = g_int_float.datau8[1];
            UartTx1Buf[2] = g_int_float.datau8[2];
            UartTx1Buf[3] = g_int_float.datau8[3];


            UartTx1Buf[4] = 0x00;
            UartTx1Buf[5] = 0x00;
            UartTx1Buf[6] = 0x80;
            UartTx1Buf[7] = 0x7f;

            rt_device_write(uart1_serial, 0, UartTx1Buf, 8);
            rt_thread_delay(1);
        }
//        rt_thread_delay(200);
    }
}
/*********************************************************************************/

/*********************************************************************************/
/* 初始化ADC线程
 */
int G_InitADCThread_i32()
{
    if(L_ADCInit_i32() != RT_EOK)
    {
        LOG_E("init ADC1 err !");
        return RT_ERROR;
    }

    /* 初始化信号量 */
    rt_sem_init(&adc_done_sem, "adc1_sem", 0, RT_IPC_FLAG_FIFO);

    rt_thread_t thread = rt_thread_create("ADC1_serial", G_ADC_thread_entry, RT_NULL, 2048, 1, 10);
    if(thread != RT_NULL)
    {
        rt_thread_startup(thread);
        LOG_I("run adc1.");
    }
    else
    {
        LOG_E("create ADC1 thread failed !");
        return RT_ERROR;
    }

    return RT_EOK;
}
/*********************************************************************************/

/*********************************************************************************/

/*********************************************************************************/
/* 初始化发送ADC数据的串口
 */
int G_ADCUartInit_i32(void)
{
    int ret = 0;

    /* 查找系统中的串口设备 */
    uart1_serial = rt_device_find(UART485);
    if(uart1_serial == RT_NULL)
    {
        LOG_E("find %s failed !", UART485);
        return RT_ERROR;
    }

    /* 修改串口配置参数 */
    Uart485Config.baud_rate = BAUD_RATE_115200;      //波特率
    Uart485Config.data_bits = DATA_BITS_8;           //数据位 8
    Uart485Config.stop_bits = STOP_BITS_1;           //停止位 1
    Uart485Config.bufsz     = 512 * 2;               //修改缓冲区 buff size
    Uart485Config.parity    = PARITY_NONE;           //无奇偶校验位
    rt_device_control(uart1_serial, RT_DEVICE_CTRL_CONFIG, &Uart485Config);

    /* 以 中断接收、轮询发送 模式打开串口设备 */
    rt_device_open(uart1_serial, RT_DEVICE_FLAG_INT_RX);

    return ret;
}
INIT_APP_EXPORT(G_ADCUartInit_i32);   //在main函数前初始化此线程

/*********************************************************************************/

#define ctrl_485_pin_num  GET_PIN(A, 8)

int G_gpio_Ctrl(void) //485控制脚
{

    rt_pin_write(ctrl_485_pin_num, 1);
    rt_pin_mode(ctrl_485_pin_num, PIN_MODE_OUTPUT);
    rt_pin_write(ctrl_485_pin_num, 1);

    return RT_EOK;
}
INIT_APP_EXPORT(G_gpio_Ctrl);      //此函数会在main函数前执行
/*********************************************************************************/




//rt_err_t g_GetADCData()
//{
//    rt_adc_device_t pAdcDev;
//    rt_uint32_t data1, data2, data3;
//
//    /* 查找设备 */
//    pAdcDev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
//    if (pAdcDev == RT_NULL)
//    {
//        LOG_E("adc1 not find !");
//        return RT_ERROR;
//    }
//
//    rt_adc_enable(pAdcDev, ADC_DEV_CHANNEL);
//    rt_adc_enable(pAdcDev, ADC_FuShe_CHANNEL);
//    rt_adc_enable(pAdcDev, ADC_REF_CHANNEL);
//
//    data1 = rt_adc_read(pAdcDev, ADC_DEV_CHANNEL);
//    data2 = rt_adc_read(pAdcDev, ADC_FuShe_CHANNEL);
//    data3 = rt_adc_read(pAdcDev, ADC_REF_CHANNEL);
//
//
//    LOG_D("dev:%f, fushe:%f, ref:%f",
//            (float)data1 / 4095.0f * 3.3f,
//            (float)data2 / 4095.0f * 3.3f,
//            (float)data3 / 4095.0f * 3.3f);
//
//    rt_adc_disable(pAdcDev, ADC_DEV_CHANNEL);
//    rt_adc_disable(pAdcDev, ADC_FuShe_CHANNEL);
//    rt_adc_disable(pAdcDev, ADC_REF_CHANNEL);
//
//    return RT_EOK;
//}
